perm filename MGRAPH.PUB[HAL,HE]2 blob sn#129805 filedate 1974-11-14 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.gph:NEWSS GRAPH STRUCTURES
C00010 ENDMK
C⊗;
.gph:NEWSS GRAPH STRUCTURES

Affixments are  stored in  both the  compiler and  the runtime by means of a
graph structure.  The nature of this structure is described 
in {sssref rgf}.
Suffice it here to say  that if the value
of  a variable is needed,  and that  value is marked as invalid, then
the list of calculator expressions for that variable  is searched for
one which can compute a  valid value; if none of the calculators will
work
(for example, they all depend themselves on invalid values),
 then the current (invalid) value is returned as the best answer
available. When  a new  value is  assigned to  a variable, all  those
values  whose  calculators depend  on  the new  value  are  marked as
invalid,  so that the next time they are needed,  graph  searching is
performed. Building  a graph  structure therefore  involves specifying
the  calculators for all  variables.   Usually, this will  be be done
implicitly by means  of the AFFIX
and  UNFIX primitives.   However,   'AL also  supplies primitives  for explicit
manipulation of  graph  structure.    The  principal  explicit  means
employed for this purpose is the %4graph assignment statement%*:
.UNFILL
	<variable> <= <expression>
.REFILL
where "<="  may  be read  "is computed  by".   This construct  causes
<expression>  to be added to  the list of  calculators for <variable>.
Similarly, 
.UNFILL
	<variable> <≠ <expression>
.REFILL
causes <expression> to be removed from the list of calculators, and 
.UNFILL
	<variable> <<= <expression>
.REFILL
replaces the current calculator list for <expression>. The statement
.UNFILL
	<variable> <<= ;
.REFILL
would cause the calculator list to be set to null. 

It is frequently very inconvenient to retype an entire  expression in
order to remove it from the calculator  list.  'AL allows the user to
attach a name to an expression in a graph assignment statement by use
of the construct
.UNFILL
	<variable> <= "id" <expression>
.REFILL
Then the construct
.UNFILL
	<variable> <≠ "id"
.REFILL
will remove  the  named expression  from the  calculator  list.   For
instance,
.UNFILL
	F1 <= "foo" T*F2;
	:
	F1 <≠ "foo";
.REFILL
would have the same effect as
.UNFILL
	F1 <= T*F2;
	:
	F1 <≠ T*F2;
.REFILL
In addition to the calculator  list,  a list of %4updater%* routines is
associated with every variable.  These routines are executed whenever
the variable value  is changed.   Initially, the list of  updaters is
empty.  However, the construct
.UNFILL
	WHEN CHANGING <variable> ALSO DO <label>: <statement>;
.REFILL
will  cause  <statement> to  be added  to  the list  of  updaters for
<variable>. (the label is optional, but is necessary if  the <statement>
is ever  to be removed from  the updater list.) In  <statement>,  the
reserved  words OLD and NEW may  be used to refer  to the old and new
values of var, respectively.  For instance:
.UNFILL
	WHEN CHANGING f2 ALSO DO foo: f1 ← NEW*(OLD → F1);
.REFILL
Updaters may be removed from the updater list by the statement
.UNFILL
	WHEN CHANGING <variable> DONT DO <label>
.REFILL
For our above example, this would be
.UNFILL
	WHEN CHANGING f2 DONT DO foo;
.REFILL
The form 
.UNFILL
	WHEN CHANGING <variable> ONLY DO <statement>; 
.REFILL
replaces the updater list with one containing just <statement>, and
.UNFILL
	WHEN CHANGING <variable> ONLY DO ;
.REFILL
clears the updater list completely.  Since the affix structure makes
use of updater and calculator  lists (see {sssref rgf}), careless use of the
replacement form is not advised.

One possible use for updater routines is tracing.  For example,
.UNFILL
	WHEN CHANGING v ALSO DO
		WRITE("The value of V is now ",NEW);
.REFILL
Details of the  graph structure algorithms  may be found  in the appendix
on runtime routines.
One  additional point that should be  mentioned here is that the
updater routines  for a  variable are %4not%* called  if the  variable's
value is modified  as a side effect  of a change to  some variable in
one of its calculators.

.gat: NEWSSS CONCERNING AFFIX AND UNFIX

The AFFIX and UNFIX statements are defined by their effects on  the
graph structures.
.UNFILL
	AFFIX f1 TO f2 BY t1
.UNFILL
is equivalent to
.REFILL
	t1 ← f2 → f1;
	f1 <= "xxx" t1 * f2;
	WHEN CHANGING f1 ALSO DO "yyy" t1 ← (f2 → NEW);
	ASSERT FACT(AFFIXED, f1, f2, t1); 
.REFILL
Then, 
.UNFILL
	UNFIX f1 FROM f2;
.REFILL
is equivalent to 
.UNFILL
	f1 <≠ "xxx";
	WHEN CHANGING f1 DONT DO yyy;
	DENY FACT(AFFIXED, f1, f2, ANYTHING);
	ASSERT FACT(WAS_AFFIXED, f1, f2);
.REFILL
Similarly,
.UNFILL
	AFFIX f1 TO f2 BY t1 RIGIDLY
.REFILL
is equivalent to
.UNFILL
	t1 ← f2 → f1;
	f1 <= t1 * f2;
	f2 <= INVERSE(t1) * f1     .
.REFILL